package com.tanhua.app.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.api.db.UserApi;
import com.tanhua.api.db.UserInfoApi;
import com.tanhua.api.mongo.FriendApi;
import com.tanhua.api.mongo.UserLikeApi;
import com.tanhua.app.interceptor.UserHolder;
import com.tanhua.autoconfig.template.AipFaceTemplate;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.autoconfig.template.SmsTemplate;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserFreeze;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.vo.*;
import com.tanhua.manager.api.db.UserFreezeApi;
import com.tanhua.util.JwtUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;
import java.util.*;

@Service // 这里使用spring的注解
public class UserService {

    @Reference
    private UserApi userApi;

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private UserLikeApi userLikeApi;
    @Reference
    private FriendApi friendApi;

    @Autowired
    private MessageService messageService;

    public ResponseEntity findByPhone(String phone) {
        User user = userApi.findByPhone(phone);
        return ResponseEntity.ok(user);
    }

    public ResponseEntity saveUser(User user) {
        Long userId = userApi.saveUser(user);
        return ResponseEntity.ok(userId);
    }

    // 发送短信验证码
    public ResponseEntity login(String phone) {
        // 1.生成6位随机数
        String code = RandomUtil.randomNumbers(6);
        code = "123456"; // TODO  上线之前恢复短信发送功能
        // 2.调用sms模板发送验证码
        // smsTemplate.sendSms(phone, code);
        // 3.将验证码存储到 redis中
        stringRedisTemplate.opsForValue().set("SMS_CODE_" + phone, code, Duration.ofMinutes(5));
        return ResponseEntity.ok(null);
    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;


    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Reference
    private UserFreezeApi userFreezeApi;

    // 用户登录、注册
    public ResponseEntity loginVerification(String phone, String vCode) {
        // 1.校验短信验证码
        String redisCode = stringRedisTemplate.opsForValue().get("SMS_CODE_" + phone);
        if (!StrUtil.equals(vCode, redisCode)) {
            return ResponseEntity.status(500).body(ErrorResult.loginError()); // 返回验证码错误
        }

        // 删除redis验证码
        stringRedisTemplate.delete("SMS_CODE_" + phone);

        // 2.根据手机号查询
        User user = userApi.findByPhone(phone);

        // 用户标记
        Boolean isNew = false;

        String type="0101"; // 登录日志

        // 3.如果没查询，注册
        if (user == null) {
            user = new User();
            user.setPhone(phone);
            user.setPassword(SecureUtil.md5("123456"));
            Long userId = userApi.saveUser(user);
            user.setId(userId);
            isNew = true;

            // 注册环信
            huanXinTemplate.register(userId);

            type="0102"; // 注册日志
        }

        // mq发送日志消息
        Map<String,String> message= new HashMap<>();
        message.put("userId", user.getId().toString());
        message.put("type", type);
        message.put("logTime", DateUtil.format(new Date(), "yyyy-MM-dd"));
        message.put("place", "北京市-顺义区"); // 这里可以查询mongo
        message.put("equipment", "小米11");
        rocketMQTemplate.convertAndSend("tanhua-log", message);



        // 3.1 将用户信息生成token，存储到redis中
        Map claims = new HashMap();
        claims.put("id", user.getId());
        claims.put("phone", phone);
        String token = JwtUtil.createToken(claims);

        // 将user对象转为json
        String json = JSON.toJSONString(user);

        // 用户认证信息存储1天
        stringRedisTemplate.opsForValue().set("TOKEN_" + token, json, Duration.ofDays(1));

        // 返回结果
        Map result = new HashMap();
        result.put("token", token);
        result.put("isNew", isNew);
        UserInfo userInfo = userInfoApi.findByUserId(user.getId());
        UserFreeze userFreeze = userFreezeApi.findById(user.getId());
        if ("2".equals(userInfo.getUserStatus()) && (userFreeze.getLogin() == 1)) {
            result.clear();
            return ResponseEntity.status(500).body(ErrorResult.freezeError());

        }
        return ResponseEntity.ok(result);
    }

    // 根据token查询用户对象
    public User findUserByToken(String token) {
        String json = stringRedisTemplate.opsForValue().get("TOKEN_" + token);

        if (StrUtil.isEmpty(json)) {
            return null;
        }

        // 转为java对象
        User user = JSON.parseObject(json, User.class);

        // 续期
        stringRedisTemplate.opsForValue().set("TOKEN_" + token, json, Duration.ofDays(1));
        return user;
    }

    // 完善个人信息
    public void loginReginfo(UserInfo userInfo, String token) {
        // 1、根据token获取用户对象
        User user = findUserByToken(token);
        // 2、userInfo指定用户id
        userInfo.setId(user.getId());
        //用户个人信息用状态初始化1正常
        userInfo.setUserStatus("1");
        // 3、调用rpc保存
        userInfoApi.save(userInfo);
    }

    // 完善头像信息
    public ResponseEntity loginReginfoPic(MultipartFile headPhoto, String token) throws Exception {
        // 1、根据token获取用户对象
        User user = findUserByToken(token);
        // 2、人脸识别
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if (!detect) { // 检测失败
            return ResponseEntity.status(500).body(ErrorResult.faceError());
        }

        // 3、oss文件上传
        String url = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        // 4、更新userInfo
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setAvatar(url); // 头像
        userInfo.setCoverPic(url); // 封面

        userInfoApi.update(userInfo);

        return ResponseEntity.ok(null);
    }

    public ResponseEntity findUserInfoVo(Long userID) {
        // 1、调用rpc根据id查询
        UserInfo info = userInfoApi.findByUserId(userID);
        // 2、转为vo对象
        UserInfoVo vo = new UserInfoVo();
        // 复制来源对象中的属性到目标对属性中
        BeanUtil.copyProperties(info, vo);
        if (info.getAge() != null) {
            vo.setAge(info.getAge().toString());
        }

        // 3、返回vo
        return ResponseEntity.ok(vo);

    }

    public ResponseEntity updateUserInfo(UserInfo userInfo, String token) {
        // 1、根据token查询用户id
        User user = findUserByToken(token);
        // 2、给userInfo绑定用户id
        userInfo.setId(user.getId());

        // 3、更新userInfo
        userInfoApi.update(userInfo);

        return ResponseEntity.ok(null);
    }

    public ResponseEntity findCounts() {
        // 1、相互喜欢
        Long eachLoveCount = userLikeApi.findEachLoveCount(UserHolder.getUserId());
        // 2、你喜欢对方
        Long loveCount = userLikeApi.findloveCount(UserHolder.getUserId());
        // 3、粉丝喜欢你
        Long fanCount = userLikeApi.findFanCount(UserHolder.getUserId());

        // 4、封装并返回vo
        return ResponseEntity.ok(new CountsVo(eachLoveCount, loveCount, fanCount));
    }

    public ResponseEntity findType(Integer pageNum, Integer pageSize, Integer type) {
        // 1、获取用户id
        Long userId = UserHolder.getUserId();

        // 2、声明返回结果
        PageBeanVo pageBeanVo = null;

        // 3、类型判断
        switch (type) {
            case 1: { // 好友
                pageBeanVo = userLikeApi.findEachLoveByPage(pageNum, pageSize, userId);
                break;
            }
            case 2: { // 我喜欢
                pageBeanVo = userLikeApi.findloveByPage(pageNum, pageSize, userId);
                break;
            }
            case 3: { // 粉丝
                pageBeanVo = userLikeApi.findFanByPage(pageNum, pageSize, userId);
                break;
            }
            case 4: { // 谁看过我
                pageBeanVo = userLikeApi.findVisitorByPage(pageNum, pageSize, userId);
                break;
            }
        }

        // 4、封装 vo
        List<UserLikeListVo> voList = new ArrayList<>();
        List<RecommendUser> recommendUserList = (List<RecommendUser>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(recommendUserList)) {
            for (RecommendUser recommendUser : recommendUserList) {
                UserLikeListVo vo = new UserLikeListVo();
                UserInfo userInfo = userInfoApi.findByUserId(recommendUser.getUserId());
                BeanUtil.copyProperties(userInfo, vo);
                vo.setMatchRate(recommendUser.getScore().intValue()); // 缘分值

                voList.add(vo);
            }
        }

        pageBeanVo.setItems(voList);

        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity fansLike(Long likeUserId) {
        // 1、添加好友关系（相互喜欢）
        messageService.addContacts(likeUserId);
        // 2、删除粉丝喜欢你的记录
        userLikeApi.removeUserLike(likeUserId, UserHolder.getUserId());
        return ResponseEntity.ok(null);
    }

    public ResponseEntity fansDisLike(Long uid) {
        userLikeApi.removeUserLike(UserHolder.getUserId(), uid);
        stringRedisTemplate.delete("Like_User_" + UserHolder.getUserId() + "_" + uid);
        friendApi.remove(UserHolder.getUserId(), uid);
        return ResponseEntity.ok(null);
    }
}
